package com.subumbo.audio.processing
{
	public class LowPass2pole 
	{
		private var a0:Number;
		private var a1:Number;
		private var a2:Number;
		private var b1:Number;
		private var b2:Number;
		
		private var mCutoff:Number;
		private var mResonance:Number;
		
		private var x_1:Number = 0;
		private var x_2:Number = 0;
		private var y_1:Number = 0;
		private var y_2:Number = 0;
		
		
		public function LowPass2pole()
		{
			a0 = 0;
			a1 = 0;
			a2 = 0;
			b1 = 0;
			b2 = 0;
			mCutoff = 0;
			mResonance = 0;		
		}
		
		
		private function updateCoefs(cutoff:Number, resonance:Number):void
		{
			trace ("updating Coefficients");
			var r:Number = Math.pow(10.0, 0.05 * -resonance);		// convert from decibels to linear

		    var k:Number = 0.5 * r * Math.sin(Math.PI * cutoff);
		    var c1:Number = 0.5 * (1.0 - k) / (1.0 + k);
		    var c2:Number = (0.5 + c1) * Math.cos(Math.PI * cutoff);
		    var c3:Number = (0.5 + c1 - c2) * 0.25;
		    //coefficients
		    a0 = 2.0 *   c3;			
		    a1 = 2.0 *   2.0 * c3;
		    a2 = 2.0 *   c3;
		    b1 = 2.0 *   -c2;
		    b2 = 2.0 *   c1;
		}
		
		
		public function filterFunc(samples:Array, cutoff:Number, resonance:Number):Array
		{
			if ((cutoff != mCutoff ) || (resonance != mResonance))
			{
				cutoff = (cutoff * 2)/44100;
				updateCoefs(cutoff, resonance);
			}
			var len:int = samples.length;
			var out:Array = new Array(len);
			for (var i:int = 0; i < len; i++)
			{
				var x:Number = samples[i] ; //read from our sample buffer
				//standard IIR filter function
				//y[n] = a0*x[n] + a1*x[n-1] + a2*x[n-2] - b1*y[n-1] - b2*y[n-2]
				out[i] = x*a0 + x_1*a1 + x_2*a2 - y_1*b1 - y_2*b2;
				
				x_2 = x_1;
				x_1 = x;
				y_2 = y_1;
				y_1 = out[i];
			}
			return out;
		}
		
		
		public function filterSample(sample:Number, cutoff:Number, resonance:Number):Number
		{
			if ((cutoff != mCutoff ) || (resonance != mResonance))
			{
				mCutoff = cutoff;
				mResonance = resonance;
				cutoff = (cutoff * 2)/44100;
				updateCoefs(cutoff, resonance);
			}
			var out:Number = 0;
			out = sample*a0 + x_1*a1 + x_2*a2 - y_1*b1 - y_2*b2;
			
			x_2 = x_1;
			x_1 = sample;
			y_2 = y_1;
			y_1 = out;
			return out;
		}
		
		
	}
}